From 56b36694110dab4db2f540db704e31c8d5934247 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 30 Jun 2020 14:15:53 -0400 Subject: [PATCH] x11: Avoid thawing surface until frame is drawn Since commit 972134abe48a4c9c7b6ad41b0723f30f4e7ae16b a frame getting drawn has three states (with the vendor nvidia driver at least): 1. drawn by gtk waiting on the GPU 2. drawn by GPU waiting on the compositor 3. drawn by compositor Those three states are encoded in two flags: frame_pending and frame_still_painting. frame_pending means step 1 is done, but step 2 and 3 are still in progress. frame_still_painting means step 2 is still in progress. After step 1 is finished the surface is frozen until step 3 is finished. When the compositor notifies gtk it's done with step 3, with a _NET_WM_FRAME_DRAWN client message, the toolkit thaws the surface to allow the next frame to proceed. The compositor sometimes sends gtk a _NET_WM_FRAME_DRAWN client message between steps 1 and 2. This message should be ignored because it's not a reply to the current frame. Unfortunately, gtk currently assumes if it gets a _NET_WM_FRAME_DRAWN client message while waiting for step 2 that it's actually at step 3, and proceeds to draw a new frame while the existing frame is still pending, leading to a blown assertion. This commit addresses the problem by ignoring _NET_WM_FRAME_DRAWN client messages from the compositor unless actually expecting one. Fixes: #2902 --- gdk/x11/gdkdisplay-x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 9804d0ea79..ca337066b8 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -1184,7 +1184,7 @@ _gdk_wm_protocols_filter (const XEvent *xevent, if (timings) timings->drawn_time = frame_drawn_time; - if (surface_impl->toplevel->frame_pending) + if (!surface_impl->toplevel->frame_still_painting && surface_impl->toplevel->frame_pending) { surface_impl->toplevel->frame_pending = FALSE; gdk_surface_thaw_updates (win); -- 2.30.2